#include "sensorsystem.h"


SensorSystem::SensorSystem()
{}

LatitudeKeyPair SensorSystem::GetTreeKey(int id) const
{
	SensorPtr currPtr = _sensorHash.FindKey(id);
	return LatitudeKeyPair(currPtr->GetLatitude(), id);
}

void SensorSystem::AddSensor (int id, Rational latitude, Rational temperature)
{
	if (id<0 || latitude<0 || temperature<0)
	{
		throw InvalidInputExcpetion();
	}

	SensorPtr newSensor(new Sensor(id, latitude, temperature));

	try
	{
		_sensorHash.InsertKey(id, newSensor);
		LatitudeKeyPair key(latitude, id);
		_sensorTree.InsertKey(key, newSensor);
	}
	catch (const KeyAlreadyInHashException&)
	{
		throw FailureException();
	}
	catch (const KeyAlreadyInTreeException&)
	{
		throw FailureException();
	}
}

void SensorSystem::RemoveSensor (int id)
{
	if (id<0)
	{
		throw InvalidInputExcpetion();
	}

	try
	{
		LatitudeKeyPair key = GetTreeKey(id);
		_sensorTree.DeleteKey(key);
		_sensorHash.DeleteKey(id);
	}
	catch (const KeyNotInTreeException&)
	{
		throw FailureException();
	}
	catch (const KeyNotInHashException&)
	{
		throw FailureException();
	}
}

void SensorSystem::ChangeSensorTemp (int id, Rational temp)
{
	if (id<0 || temp<0) {
		throw InvalidInputExcpetion();
	}
	try
	{
		SensorPtr ptr = _sensorHash.FindKey(id);
		LatitudeKeyPair key(ptr->GetLatitude(), id);
		ptr->SetTemperature(temp);
		_sensorTree.UpdateValue(key, ptr);
	}
	catch (const KeyNotInHashException&) {
		throw FailureException();
	}
}

Rational SensorSystem::GetSensorTemp (int id) const
{
	if (id<0) {
		throw InvalidInputExcpetion();
	}
	try
	{
		return _sensorHash.FindKey(id)->GetTemperature();
	}
	catch (const KeyNotInHashException&) {
		throw FailureException();
	}
}

Rational SensorSystem::AverageTempInRange(Rational fromLatitude, Rational toLatitude) const
{
	if (fromLatitude<0 || toLatitude<0) {
		throw InvalidInputExcpetion();
	}
	try {
		return _sensorTree.GetAvgTemperatureByRange(fromLatitude,toLatitude);
	}
	catch(const InvalidLatitudeRangeException&) {
		throw InvalidInputExcpetion();
	}
	catch(const EmptyLatitudeRangeException&) {
		throw FailureException();
	}
}


Rational SensorSystem::MaxTempInRange(Rational fromLatitude, Rational toLatitude) const
{
	if (fromLatitude<0 || toLatitude<0) {
		throw InvalidInputExcpetion();
	}
	try {
		return _sensorTree.FindMaxTempInRange(fromLatitude, toLatitude);
	}
	catch(const InvalidLatitudeRangeException&) {
		throw InvalidInputExcpetion();
	}
	catch(const EmptyLatitudeRangeException&) {
		throw FailureException();
	}
}




